// react 组件生命周期
// 组件的生命周期  (https://segmentfault.com/a/1190000016617400?utm_source=tag-newest)
/*
 react 组件的生命周期
 含义   组件从初始化渲染到被移除或者销毁的过程  成为组件的生命周期

 1. 每个组件都有生命周期
 2. react 通过组件的生命周期钩子函数来管理 组件
 3. 系统 某些状态和参数发生改变的时候，系统立马去通知 对应处理的函数叫做钩子函数
 hooks 钩子函数  允许在特定的时期添加用户自己的代码  不同的阶段添加自己的逻辑代码

 react 组件的生命周期 分为三个阶段 
 1.mount  组件的初始化  从虚拟DOM 渲染成为真实DOM 的过程    1  
 2.update   组件的数据变化 setState  组件的state 更新 导致二次渲染的过程     n  
 3.unmount  组件销毁   组件因为路由切换而销毁 (浏览器的垃圾回收机制 )     1  

 mounted 组件载入阶段  (钩子函数  15 16 17 ) 
 0.constructor   构造器函数  纯函数组件没有 
 1.getDefaultProps   设置组件默认的props   废弃 16已经被废弃   App.defaultPorps    15 
 2.getInitialState   设置组件默认的state   废弃 16已经被废弃   this.state state = {}  15 
 3.componentWillMount  在jsx被渲染到页面之前被调用  废弃 16尚存  17警告  18马上废弃 
 3.1  getDerivedStateFromProps ( 组件每次被rerender的时候，包括在组件构建之后(虚拟dom之后，实际dom挂载之前)，每次获取新的props或state之后；;每次接收新的props之后都会返回一个对象作为新的state，返回null则说明不需要更新state)   17新增的 
 4.render   渲染函数是react中默认的函数  虚拟DOM 正在渲染成真实DOM 
 5.componentDidMount   jsx被渲染到页面后被调用   1    已经全部都是真是DOM  实例化    99.999999

*/ 
/*
update 组件数据更新阶段   组件修改 state  组件接收的props发送改变  都会进入 update 阶段 
1. componentWillReceiveProps(nextProps)  接收变化的props   废弃 16尚存  17警告   18马上废弃
2.1 getDerivedStateFromProps  获取最新的props 和 state 
2. shouldComponentUpdate  询问是否更新  true 更新 false 不更新   性能优化  
3. componentWillUpdate ==>     组件即将更新之前    废弃 16尚存  17警告 18马上废弃   
4. render   组件开始二次渲染  update  
4.1 getSnapshotBeforeUpdate  组件更新之前触发 得到旧的props和state    17新增 
5. componentDidUpdate   组件更新渲染数据完毕 

*/ 
// unMount 组件销毁移除 路由切换 
// componentDidCatch     捕获异常 
// componentWillUnmount  这个函数几乎不会使用到，因为浏览器本身具有垃圾回收机制

import React, { Component } from 'react';

class Lifedemo extends Component {
    state = {
        flag:true ,
        msg:"are you ok?"
    }
    render() {
        return (
            <div>
                <h2>React 组件生命周期 </h2>
                <button onClick={()=>this.setState({flag:!this.state.flag})}>点击切换flag </button>
                <p>
                    <input type="text" value={this.state.msg} ref={el=>this.text=el} onChange={()=>this.setState({msg:this.text.value})} />
                </p>
                <hr/>
                {
                    this.state.flag &&  <ChildDemo 
                    msg={this.state.msg}
                    />
                }
            </div>
        );
    }
}

let index = 0
class ChildDemo extends Component{
    constructor(){
        super()
        this.log("constructor - class 类组件初始化 ")
    }
    log=(msg)=>{
        console.log(`##${++index} --- ${msg}`)
    }
    // componentWillMount(){
    //     this.log('componentWillMount 组件马上要渲染之前')
    // }

    // 17 新增的  代替 componentWillMount  和  componentWillUpdate
    static getDerivedStateFromProps(){   // 静态属性函数没有 this 
        console.log(`##${++index} --- getDerivedStateFromProps 获取新的prop和state `)
        return {

        }
    }
    // 询问是否更新
    shouldComponentUpdate(){
        this.log('shouldComponentUpdate - 询问是否更新')
        return true;
        // 条件渲染  可以进行性能优化  
    }
    // componentWillUpdate(){
    //     this.log("componentWillUpdate - 组件即将更新之前 ")
    // }
    state = {
        count:1,
    }
    changeCount=()=>{
        this.setState({
            count:++this.state.count 
        })
    }
    render(){
        this.log('render  组件正在二次渲染')
        return (
            <div>
                <h2>
                    ChildDemo - 1 - 子组件 
                </h2>
                <h2>msg=={this.props.msg}</h2>
                <h2>count ==  {this.state.count}</h2>
                <button onClick={this.changeCount} >changeCount</button>
            </div>
        )
    }
    componentDidMount(){
        this.log("componentDidMount 组件载入完毕 ")
        // 请求ajax
        // 插件实例化 swiper 
    }   

    getSnapshotBeforeUpdate(){
        this.log('getSnapshotBeforeUpdate 在数据更新之前 获取旧的 state 和 prop')
        return {
            a:1,
            b:299
        }
    }

    componentDidUpdate(){
        this.log('componentDidUpdate - 组件二次更新渲染完毕')
    }

    // 组件销毁  v-if或者路由切换
    componentWillUnmount(){
        this.log('componentWillUnmount - 组件被销毁了...')
    }
    
}

export default Lifedemo